import React, { useMemo, useState } from 'react'

export type Column<T> = {
  key: keyof T
  title: string
  width?: number | string
  render?: (row: T) => React.ReactNode
  sortable?: boolean
}

type DataTableProps<T> = {
  data: T[]
  columns: Column<T>[]
  searchableKeys?: (keyof T)[]
  pageSizeOptions?: number[]
  defaultPageSize?: number
}

export function DataTable<T extends Record<string, any>>({
  data,
  columns,
  searchableKeys = [],
  pageSizeOptions = [10, 20, 50],
  defaultPageSize = 10,
}: DataTableProps<T>): JSX.Element {
  const [query, setQuery] = useState('')
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(defaultPageSize)
  const [sortKey, setSortKey] = useState<keyof T | null>(null)
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc')

  const filtered = useMemo(() => {
    if (!query) return data
    const q = query.toLowerCase()
    return data.filter(row =>
      searchableKeys.some(k => String(row[k] ?? '').toLowerCase().includes(q))
    )
  }, [data, query, searchableKeys])

  const sorted = useMemo(() => {
    if (!sortKey) return filtered
    const arr = [...filtered]
    arr.sort((a, b) => {
      const va = a[sortKey]
      const vb = b[sortKey]
      if (va == null && vb == null) return 0
      if (va == null) return -1
      if (vb == null) return 1
      if (va < vb) return sortDir === 'asc' ? -1 : 1
      if (va > vb) return sortDir === 'asc' ? 1 : -1
      return 0
    })
    return arr
  }, [filtered, sortKey, sortDir])

  const total = sorted.length
  const totalPages = Math.max(1, Math.ceil(total / pageSize))
  const currentPage = Math.min(page, totalPages)
  const start = (currentPage - 1) * pageSize
  const pageRows = sorted.slice(start, start + pageSize)

  const onSort = (key: keyof T, enabled?: boolean) => {
    if (!enabled) return
    if (sortKey === key) {
      setSortDir(sortDir === 'asc' ? 'desc' : 'asc')
    } else {
      setSortKey(key)
      setSortDir('asc')
    }
  }

  return (
    <div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 10 }}>
        <input className="input" placeholder="搜索..." value={query} onChange={e => { setQuery(e.target.value); setPage(1) }} />
        <div className="spacer" />
        <select className="select" value={pageSize} onChange={e => { setPageSize(Number(e.target.value)); setPage(1) }}>
          {pageSizeOptions.map(n => <option key={n} value={n}>{n}/页</option>)}
        </select>
      </div>
      <div className="table-wrapper">
        <table className="table">
          <thead>
            <tr>
              {columns.map(col => (
                <th key={String(col.key)} style={{ width: col.width }} onClick={() => onSort(col.key, col.sortable)}>
                  <span style={{ cursor: col.sortable ? 'pointer' : 'default' }}>
                    {col.title}
                    {sortKey === col.key && (
                      <span style={{ marginLeft: 6 }}>{sortDir === 'asc' ? '▲' : '▼'}</span>
                    )}
                  </span>
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {pageRows.map((row, i) => (
              <tr key={i}>
                {columns.map(col => (
                  <td key={String(col.key)}>
                    {col.render ? col.render(row) : String(row[col.key] ?? '')}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginTop: 10 }}>
        <div className="muted">共 {total} 条 · 第 {currentPage}/{totalPages} 页</div>
        <div className="spacer" />
        <button className="btn btn-sm" disabled={currentPage <= 1} onClick={() => setPage(1)}>首页</button>
        <button className="btn btn-sm" disabled={currentPage <= 1} onClick={() => setPage(p => Math.max(1, p - 1))}>上一页</button>
        <button className="btn btn-sm" disabled={currentPage >= totalPages} onClick={() => setPage(p => Math.min(totalPages, p + 1))}>下一页</button>
        <button className="btn btn-sm" disabled={currentPage >= totalPages} onClick={() => setPage(totalPages)}>末页</button>
      </div>
    </div>
  )
}

